--[[
##################################
####### RBG - Shared Vars ########
##################################
]]

local PLAYER_HEIGHT;
local HOSTILE_FACTION;
local FRIENDLY_FACTIOH;
local COMBAT_ACTIVE;
local MAX_LEVEL;

--[[
##################################
########## RBG - Panel ###########
##################################
]]

RatedBattlegroundPanel = inherit(Singleton)

function RatedBattlegroundPanel:constructor()
	self.m_Enemys = {}
	self.m_EnemysByName = {}
	self.m_MateTargets  = {}
	self.m_IsOnBattleground = false
	self.m_PreviousTarget = false
	
	self.m_EventFrame = CreateFrame("Frame",nil)
	
	-- Register Events
	
	self.m_EventFrame:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")
	self.m_EventFrame:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
	self.m_EventFrame:RegisterEvent("ZONE_CHANGED_NEW_AREA")	
	self.m_EventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")	
	self.m_EventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")	
	self.m_EventFrame:RegisterEvent("UNIT_TARGET")	
	
	self.m_EventFrame:SetScript("onEvent", bind(self.OnEvent,self))
	
	self:Ready()
end

function RatedBattlegroundPanel:RegisterName(name,instance) self.m_EnemysByName[name] = instance end
function RatedBattlegroundPanel:UnregisterName(name) self.m_EnemysByName[name] = nil end

function RatedBattlegroundPanel:OnEvent(frame,event,...)
	if event == "PLAYER_REGEN_DISABLED" then
		COMBAT_ACTIVE = true
	elseif event == "PLAYER_REGEN_ENABLED" then
		COMBAT_ACTIVE = false
	end
	-- Do this at least
	if self[event] then
		self[event](self,...)
	end
end

function RatedBattlegroundPanel:UNIT_TARGET(unit)
	if self.m_IsOnBattleground and RBG.VALIDUNITS[unit] then
		local target = unit.."target"
		local targetName = GetUnitName(target,true)
		if not targetName or not self:GetButtonByName(targetName) then return end
		local targetInstance = self:GetButtonByName(targetName)
		targetInstance:SetTargetCount(0) -- Reset
		local count = 0
		for i = 1, self.m_Size, 1 do
			if GetUnitName(("raid%dtarget"):format(i),true) == targetName then
				count = count + 1
			end
		end
		targetInstance:SetTargetCount(count)
	end
end

function RatedBattlegroundPanel:GetButtonByName(name)
	return self.m_EnemysByName[name] or false
end

function RatedBattlegroundPanel:Ready()
	self.m_MainFrame = CreateFrame("Frame",RBG.FRAMENAME,UIParent)
	self.m_MainFrame:SetHeight(RBG.HEIGHT)
	self.m_MainFrame:SetWidth(RBG.WIDTH)
	self.m_MainFrame:SetPoint("LEFT",50,108)
	self.m_Background = self.m_MainFrame:CreateTexture(RBG.FRAMENAME.."_TEXTURE","BACKGROUND")
	self.m_Background:SetTexture(0,0,0,1)
	self.m_Background:SetAllPoints(self.m_MainFrame)
	self.m_MainFrame:RegisterForDrag("MiddleButton")
	self.m_MainFrame:EnableMouse(true)
	self.m_MainFrame:SetMovable(true)
	self.m_MainFrame:SetClampedToScreen(true)
	self.m_MainFrame:SetScript("OnDragStart", self.m_MainFrame.StartMoving)
	self.m_MainFrame:SetScript("OnDragStop", self.m_MainFrame.StopMovingOrSizing)		
	
	self.m_MainFrame:Show()
end

function RatedBattlegroundPanel:WipeExistingFrames ()
	for key, value in pairs(self.m_Enemys) do
		value:SetBusy()
		self.m_Enemys[key] = nil
	end
	self.m_Enemys = {} -- Fix: if a issue appeared
end

function RatedBattlegroundPanel:FillUpList()
	self:WipeExistingFrames()
	RequestBattlefieldScoreData()
	for key, value in ipairs(self:GetSortedList()) do
		if not COMBAT_ACTIVE then
			self.m_Enemys[key] = RatedBattlegroundPlayer:new(value.ID,key)
		end
	end
end

function RatedBattlegroundPanel:GetSortedList()
	local tbl = {}
	for key, value in ipairs(self:GetFaction(HOSTILE_FACTION)) do
		local name,_,_,_,_,faction,_,_,classEN,_,_,_,_,_,_,talentSpec = GetBattlefieldScore(value)
		local classData = CLASS_SPECS[classEN][talentSpec]	
		tbl[key] = { ID = value, ROLE = classData.ROLE }
	end
	table.sort ( tbl, function(d,e) return d.ROLE < e.ROLE end )
	return tbl
end

function RatedBattlegroundPanel:IsEnemyTeamFull()
	if #self:GetFaction(HOSTILE_FACTION) == self.m_Size then
		return true
	end
	return false
end

function RatedBattlegroundPanel:GetFaction(fct)
	local t = {}
	for i = 1, GetNumBattlefieldScores() do
		local name,_,_,_,_,faction = GetBattlefieldScore(i) -- 0 = horde; 1 = alliance;
		if faction == fct then
			t[#t+1] = i
		end
	end
	return t
end

function RatedBattlegroundPanel:SetFactions()
	for i = 1, GetNumBattlefieldScores() do
		local name,_,_,_,_,faction = GetBattlefieldScore(i) -- 0 = horde; 1 = alliance;
		if name == CLIENT_NAME then
			FRIENDLY_FACTION = faction
			HOSTILE_FACTION  = faction == 0 and 1 or 0
		end
	end
end

function RatedBattlegroundPanel:SetValidUnits()
	table.wipe(RBG.VALIDUNITS)
	for i = 1, self.m_Size do
		RBG.VALIDUNITS["raid"..i] = true
	end
end

function RatedBattlegroundPanel:UPDATE_BATTLEFIELD_SCORE()
	if select(2,IsInInstance()) == "pvp" and RBG.SETTINGS[GetRealZoneText()] then
		self.m_IsOnBattleground = true
		self.m_Size = IsRatedBattleground() and 10 or RBG.SETTINGS[GetRealZoneText()].MAXPLAYERS
		self:SetValidUnits()
		self:SetFactions()
		PLAYER_HEIGHT = RBG.HEIGHT/self.m_Size
		if not self:IsEnemyTeamFull() or #self.m_Enemys == 0 then
			self:FillUpList()
			self:SendMessage(LGET"Filling playerlist")
		end
	else
		self.m_IsOnBattleground = false
		self:WipeExistingFrames()
	end
end
RatedBattlegroundPanel.ZONE_CHANGED_NEW_AREA     = RatedBattlegroundPanel.UPDATE_BATTLEFIELD_SCORE
RatedBattlegroundPanel.UPDATE_BATTLEFIELD_STATUS = RatedBattlegroundPanel.UPDATE_BATTLEFIELD_SCORE


function RatedBattlegroundPanel:SendMessage(msg,...)
	print(LGET("Default Message")..msg,...)
end

--[[
##################################
##### RBG - Player Frames ########
##################################
]]

RatedBattlegroundPlayer = inherit(Object)

function RatedBattlegroundPlayer:constructor(id,sortID)
	self.m_Id = id
	self.m_SortID = sortID
	self.m_Button = CreateFrame("Button",("%s_UNIT%d"):format(RBG.FRAMENAME,self.m_SortID),RatedBattlegroundPanel:getSingleton().m_MainFrame,"SecureActionButtonTemplate")
	self.m_Button:SetWidth(RBG.WIDTH)
	self.m_Button:SetHeight(PLAYER_HEIGHT)
	self.m_Button:SetPoint("LEFT",0,((self.m_SortID-1)*-PLAYER_HEIGHT)+RBG.HEIGHT/2-PLAYER_HEIGHT/2)
	self.m_Button:SetScript("onEvent",bind(self.onEvent,self))
	self.m_Button:RegisterEvent("UNIT_HEALTH_FREQUENT")
	
	self.m_Button:SetBackdrop({
		edgeFile = "",
		edgeSize = 4,
	})

	self.m_Button.FRAME = self.m_Button:CreateTexture(("%s_UNIT%d_TEXTURE_FRAME"):format(RBG.FRAMENAME,self.m_Id),"HIGHLIGHT")
	self.m_Button.FRAME:SetTexture(0,0,0,0)
	self.m_Button.FRAME:SetAllPoints()

	self.m_Button.BACKGROUND = self.m_Button:CreateTexture(("%s_UNIT%d_TEXTURE_BACKGROUND"):format(RBG.FRAMENAME,self.m_Id),"BACKGROUND")
	self.m_Button.BACKGROUND:SetTexture(0.5,0,0,0.1)
	self.m_Button.BACKGROUND:SetPoint("LEFT",self:GetAddWidth(),0)
	self.m_Button.BACKGROUND:SetWidth(RBG.WIDTH-self:GetAddWidth())
	self.m_Button.BACKGROUND:SetHeight(PLAYER_HEIGHT)	
	
	self.m_Button.HEALTHBAR = self.m_Button:CreateTexture(("%s_UNIT%d_TEXTURE_HEALTHBAR"):format(RBG.FRAMENAME,self.m_Id),"OVERLAY")
	self.m_Button.HEALTHBAR:SetTexture(0.5,0,0,0.1)
	self.m_Button.HEALTHBAR:SetPoint("LEFT",self:GetAddWidth(),0)
	self.m_Button.HEALTHBAR:SetWidth(RBG.WIDTH-self:GetAddWidth())
	self.m_Button.HEALTHBAR:SetHeight(PLAYER_HEIGHT-1) -- Remove 0.5 pixel for better separation
	
	self.m_Button.NAME = self.m_Button:CreateFontString(nil, "OVERLAY", "GameTooltipText")
	self.m_Button.NAME:SetPoint("LEFT",5+RBG.WIDTH/RBG.ADD_DIV*2,0)
	self.m_Button.NAME:SetTextColor(0,0,0,1)
	self.m_Button.NAME:SetText("")	
	
	self.m_Button.CLASS_ICON = self.m_Button:CreateTexture(("%s_UNIT%d_TEXTURE_CLASS_ICON"):format(RBG.FRAMENAME,self.m_Id),"ARTWORK")
	self.m_Button.CLASS_ICON:SetTexture(1,1,1,1)
	self.m_Button.CLASS_ICON:SetPoint("LEFT",0,0)
	self.m_Button.CLASS_ICON:SetWidth(RBG.WIDTH/RBG.ADD_DIV)
	self.m_Button.CLASS_ICON:SetHeight(PLAYER_HEIGHT)
	
	self.m_Button.ROLE_ICON = self.m_Button:CreateTexture(("%s_UNIT%d_TEXTURE_ROLE_ICON"):format(RBG.FRAMENAME,self.m_Id),"ARTWORK")
	self.m_Button.ROLE_ICON:SetTexture(1,1,1,1)
	self.m_Button.ROLE_ICON:SetPoint("LEFT",RBG.WIDTH/RBG.ADD_DIV,0)
	self.m_Button.ROLE_ICON:SetWidth(RBG.WIDTH/RBG.ADD_DIV)
	self.m_Button.ROLE_ICON:SetHeight(PLAYER_HEIGHT)	
	
	self.m_Button:RegisterForClicks("AnyUp")
	self:Ready()
end

function RatedBattlegroundPlayer:SetTargetCount(i)
	self.m_Targets = i
	self.m_Button.NAME:SetText(string.split(self.m_Name,"-")[1]..self.m_Targets)
end

function RatedBattlegroundPlayer:Ready()
	local name,_,_,_,_,faction,_,_,classEN,_,_,_,_,_,_,talentSpec = GetBattlefieldScore(self.m_Id)
	local classData = CLASS_SPECS[classEN][talentSpec]
	local r,g,b = unpack(CLASS_COLOR[classEN] or {1,1,1})
	self.m_Name = name
	self.m_Targets = 0
	RatedBattlegroundPanel:getSingleton():RegisterName(self.m_Name,self)
	self.m_Button:SetAttribute("type1", "macro")
	self.m_Button:SetAttribute("macrotext1", "/target "..self.m_Name)
	self.m_Button.BACKGROUND:SetTexture(r,g,b,0.3)
	self.m_Button.HEALTHBAR:SetTexture(r,g,b,1)
	self.m_Button.NAME:SetText(string.split(self.m_Name,"-")[1]..self.m_Targets)
	self.m_Button.CLASS_ICON:SetTexture(classData.ICON)
	self.m_Button.ROLE_ICON:SetTexture("Interface/LFGFRAME/LFGROLE.png")
	self.m_Button.ROLE_ICON:SetTexCoord(unpack(CLASS_ROLE_COORD[classData.ROLE]))
	return self
end

function RatedBattlegroundPlayer:GetAddWidth()	
	-- ToDo: Connect later with the Manager
	local mul = 2
	return (RBG.WIDTH/RBG.ADD_DIV)*mul
end

function RatedBattlegroundPlayer:onEvent(_,event,...)
	if event == "UNIT_HEALTH_FREQUENT" then
		local unit      = select(1,...)
		local targetID  = unit.."target"
		if GetUnitName(targetID,true) == self.m_Name then
			local currentHP = UnitHealth(targetID) >= 0 and UnitHealth(targetID) or 0
			local maxHP     = UnitHealthMax(targetID)
			local barSize   = RBG.WIDTH-self:GetAddWidth()
			self.m_Button.HEALTHBAR:SetWidth(barSize*(currentHP/maxHP))
		end
	end
end

function RatedBattlegroundPlayer:SetBusy()
	self.m_Targets = 0
	RatedBattlegroundPanel:getSingleton():UnregisterName(self.m_Name)
	self.m_Button:Hide()
end